package com.arvin.faceDetect.utils

import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Rect
import android.util.Log
import kotlin.math.abs

/**
 * 图像分析器
 * 用于分析图像质量和光照条件，包括：
 * 1. 光照条件分析
 * 2. 图像质量评估
 * 3. 图像清晰度评估
 */
object ImageAnalyzer {
    // 光照条件阈值
    private const val GOOD_LIGHTING_MIN = 80       // 降低最小亮度要求
    private const val GOOD_LIGHTING_MAX = 220      // 提高最大亮度限制
    private const val ACCEPTABLE_LIGHTING_MIN = 40  // 降低可接受的最小亮度
    private const val ACCEPTABLE_LIGHTING_MAX = 255 // 提高可接受的最大亮度
    private const val MAX_LIGHTING_VARIANCE = 80f   // 提高方差容忍度

    /**
     * 光照质量枚举
     */
    enum class LightingQuality {
        POOR,    // 光照不足或过强
        FAIR,    // 光照一般
        GOOD     // 光照良好
    }

    /**
     * 光照条件数据类
     */
    data class LightingCondition(
        val quality: LightingQuality,
        val brightness: Float,
        val contrast: Float
    )

    /**
     * 图像质量数据类
     */
    data class ImageQuality(
        val sharpness: Float,
        val noiseLevel: Float,
        val lightingCondition: LightingCondition
    )

    /**
     * 获取人脸区域的光照条件
     */
    fun getFaceLightingCondition(bitmap: Bitmap, faceRect: Rect): LightingCondition {
        try {
            // 计算人脸区域的亮度
            var totalBrightness = 0f
            var pixelCount = 0

            // 确保坐标在有效范围内
            val left = faceRect.left.coerceIn(0, bitmap.width - 1)
            val top = faceRect.top.coerceIn(0, bitmap.height - 1)
            val right = faceRect.right.coerceIn(0, bitmap.width)
            val bottom = faceRect.bottom.coerceIn(0, bitmap.height)

            // 创建像素数组
            val pixels = IntArray((right - left) * (bottom - top))
            bitmap.getPixels(pixels, 0, right - left, left, top, right - left, bottom - top)

            // 计算平均亮度
            pixels.forEach { pixel ->
                val r = (pixel shr 16) and 0xff
                val g = (pixel shr 8) and 0xff
                val b = pixel and 0xff
                totalBrightness += (r + g + b) / 3f
                pixelCount++
            }

            val averageBrightness = if (pixelCount > 0) totalBrightness / pixelCount else 0f
            val normalizedBrightness = averageBrightness / 255f // 归一化到0-1范围

            // 计算对比度
            var contrastSum = 0f
            pixels.forEach { pixel ->
                val r = (pixel shr 16) and 0xff
                val g = (pixel shr 8) and 0xff
                val b = pixel and 0xff
                val pixelBrightness = (r + g + b) / 3f
                contrastSum += abs(pixelBrightness - averageBrightness)
            }
            val contrast = if (pixelCount > 0) contrastSum / (pixelCount * 255f) else 0f

            // 根据亮度和对比度判断光照质量
            val quality = when {
                normalizedBrightness < 0.2f || normalizedBrightness > 0.8f -> LightingQuality.POOR
                normalizedBrightness < 0.3f || normalizedBrightness > 0.7f -> LightingQuality.FAIR
                contrast < 0.1f -> LightingQuality.POOR
                contrast < 0.2f -> LightingQuality.FAIR
                else -> LightingQuality.GOOD
            }

            Log.d(
                "ImageAnalyzer",
                "光照分析结果 - 亮度: $normalizedBrightness, 对比度: $contrast, 质量: $quality"
            )

            return LightingCondition(quality, normalizedBrightness, contrast)
        } catch (e: Exception) {
            Log.e("ImageAnalyzer", "分析光照条件失败: ${e.message}")
            return LightingCondition(LightingQuality.POOR, 0f, 0f)
        }
    }

    /**
     * 分析图像质量
     */
    fun analyzeImageQuality(bitmap: Bitmap): ImageQuality {
        // 分析清晰度
        val sharpness = calculateSharpness(bitmap)

        // 分析噪声水平
        val noise = calculateNoise(bitmap)

        // 分析光照条件
        val lighting = getFaceLightingCondition(bitmap, Rect(0, 0, bitmap.width, bitmap.height))

        return ImageQuality(
            sharpness = sharpness,
            noiseLevel = noise,
            lightingCondition = lighting
        )
    }

    /**
     * 计算图像清晰度
     */
    private fun calculateSharpness(bitmap: Bitmap): Float {
        val pixels = IntArray(bitmap.width * bitmap.height)
        bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)

        var laplacianSum = 0.0
        for (y in 1 until bitmap.height - 1) {
            for (x in 1 until bitmap.width - 1) {
                val center = getBrightness(pixels[y * bitmap.width + x])
                val top = getBrightness(pixels[(y - 1) * bitmap.width + x])
                val bottom = getBrightness(pixels[(y + 1) * bitmap.width + x])
                val left = getBrightness(pixels[y * bitmap.width + (x - 1)])
                val right = getBrightness(pixels[y * bitmap.width + (x + 1)])

                val laplacian = abs(4 * center - top - bottom - left - right)
                laplacianSum += laplacian
            }
        }

        return (laplacianSum / (bitmap.width * bitmap.height)).toFloat()
    }

    /**
     * 计算图像噪声水平
     */
    private fun calculateNoise(bitmap: Bitmap): Float {
        val pixels = IntArray(bitmap.width * bitmap.height)
        bitmap.getPixels(pixels, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height)

        var noiseSum = 0.0
        for (y in 1 until bitmap.height - 1) {
            for (x in 1 until bitmap.width - 1) {
                val center = getBrightness(pixels[y * bitmap.width + x])
                val top = getBrightness(pixels[(y - 1) * bitmap.width + x])
                val bottom = getBrightness(pixels[(y + 1) * bitmap.width + x])
                val left = getBrightness(pixels[y * bitmap.width + (x - 1)])
                val right = getBrightness(pixels[y * bitmap.width + (x + 1)])

                val avgNeighbor = (top + bottom + left + right) / 4f
                noiseSum += abs(center - avgNeighbor)
            }
        }

        return (noiseSum / (bitmap.width * bitmap.height)).toFloat()
    }

    /**
     * 获取像素的亮度值
     */
    private fun getBrightness(pixel: Int): Float {
        val r = Color.red(pixel)
        val g = Color.green(pixel)
        val b = Color.blue(pixel)
        return (r * 0.299f + g * 0.587f + b * 0.114f)
    }
} 